/*
 * ModeloTest.cpp
 *
 *  Created on: Apr 12, 2012
 *      Author: Juan Sebastian Goldberg
 */

#include "PPMCTest.h"
#include "../Modelo.h"
#include <iostream>

using namespace std;

int modeloTest()
{
	cout << endl;
	cout << "===========================" << endl;
	cout << "P R U E B A S   M O D E L O" << endl;
	cout << "===========================" << endl;
	cout << endl;

	Modelo modeloCero;
	ModeloMenosUno modeloMenosUno;

	cout << "Modelo cero recién creado tiene el símbolo ESC: " <<
			modeloCero.contiene(SimboloESC) << endl;
	cout << "Modelo menos uno recién creado NO tiene el símbolo ESC: " <<
			(not modeloMenosUno.contiene(SimboloESC)) << endl;

	FrecuenciasSimbolos fs=modeloCero.getFrecuenciasSimbolos();
	DatoSimboloModelo &dsm=fs[SimboloESC];

	cout << "La frecuencia del ESC en modelo cero es 1: " <<
			(dsm.frecuencia==1) << endl;

	bool tieneTodoLosCaracteres=true;
	for (int i=0;i<=255 && tieneTodoLosCaracteres;i++)
	{
		char c=i;
		Simbolo s=c;
		tieneTodoLosCaracteres=modeloMenosUno.contiene(s);
	}

	if (tieneTodoLosCaracteres)
		tieneTodoLosCaracteres=modeloMenosUno.contiene(SimboloEOF);

	cout << "El modelo menos uno tiene todos los caracteres incluido SimboloEOF: " <<
			tieneTodoLosCaracteres << endl;

	modeloCero.actualizarFrecuencia('a');
	cout << "Si agrego la 'a' al modelo cero, entonces contiene la 'a': " <<
		modeloCero.contiene('a') << endl;
	modeloCero.actualizarFrecuencia('b');
	cout << "Si agrego la 'b' al modelo cero, entonces contiene la 'b': " <<
		modeloCero.contiene('b') << endl;
	modeloCero.actualizarFrecuencia((char)200);
	cout << "Si agrego (char)200 al modelo cero, entonces contiene (char)200: " <<
		modeloCero.contiene((char)200) << endl;
	fs=modeloCero.getFrecuenciasSimbolos();
	cout << "Luego de haber agregado 3 simbolos distintos ESC tiene frecuencia 3: " <<
		(fs[SimboloESC].frecuencia==3) << endl;

	for (int i=0;i<100;i++)
		modeloCero.actualizarFrecuencia('a');
	fs=modeloCero.getFrecuenciasSimbolos();
	cout << "Si actualizo la frecuencia de la 'a' 100 veces " <<
		"entonces su frecuencia pasa a ser 101: " <<
		(fs['a'].frecuencia==101) << endl;
	cout << "Y la frecuencia del ESC sigue siendo 3: " <<
		(fs[SimboloESC].frecuencia==3) << endl;

	fs=modeloMenosUno.getFrecuenciasSimbolos();
	cout << "Inicialmente el modelo -1 tiene 257 simbolos: " <<
		(fs.size()==257) << endl;

	modeloMenosUno.removeSimbolo('a');
	fs=modeloMenosUno.getFrecuenciasSimbolos();
	cout << "Pero si quitamos la 'a' debería quedar en 256: " <<
		(fs.size()==256) << endl;
	cout << "Y no debería contener la 'a': " <<
		(not modeloMenosUno.contiene('a')) << endl;

	bool noExisteModeloSiguienteOrden=true;
	fs=modeloCero.getFrecuenciasSimbolos();
	FrecuenciasSimbolos::iterator ifs=fs.begin();
	while ((ifs!=fs.end()) && noExisteModeloSiguienteOrden)
	{
		noExisteModeloSiguienteOrden=
			modeloCero.getModeloSiguienteOrden(ifs->first)==NULL;

		ifs++;
	}
	cout << "Para todos los simbolos del modelo cero no existe modelo " <<
		"de siguiente orden: " << noExisteModeloSiguienteOrden << endl;

	bool noSePudoAgregarModelo=false;
	try
	{
		modeloCero.crearModeloSiguienteOrdenSiNoExiste('z');
	}catch(string &s)
	{
		noSePudoAgregarModelo=true;
	}
	cout << "Al agregar el modelo de sig orden para la 'z' obtenemos " <<
		"una excepcion: " << noSePudoAgregarModelo << endl;

	Modelo *m=modeloCero.crearModeloSiguienteOrdenSiNoExiste('a');
	fs=m->getFrecuenciasSimbolos();
	cout << "Luego de agregar un modelo para la 'a' dicho modelo tiene el ESC: " <<
			modeloCero.contiene(SimboloESC) << endl;
	cout << "De hecho tiene solo el ESC: " << (fs.size()==1) << endl;
	cout << "Su frecuencia es 1: " << (fs[SimboloESC].frecuencia==1) << endl;

	cout << "Al intentar recuperar el modelo para la 'a' debemos recuperarlo: " <<
		(modeloCero.getModeloSiguienteOrden('a')!=NULL) << endl;
	/*
	 * Pruebas especificas de conversión de caracter a Simbolo y viceversa
	 */
	/*
	unsigned char caracter=0;
	char sc;
	Simbolo simbolo=caracter;
	cout << "El unsigned char 0 es el Simbolo 0: " << (simbolo==0) << endl;

	caracter=255;
	simbolo=caracter;
	cout << "El unsigned char 255 es el Simbolo 255: " << (simbolo==255) << endl;

	sc=255;
	caracter=255;
	cout << "Un unsigned char y un signed char con valor 255 se interpretan de la misma forma: " <<
			(sc==caracter) << endl;

	simbolo=caracter;
	sc=simbolo;
	cout << "Si asigno un unsigned char con 255 en una variable " <<
		"de tipo Simbolo obtengo un 255 en otra variable char: " <<
		(sc==caracter) << endl;

	simbolo=sc;
	caracter=simbolo;
	cout << "La inversa también es válida: " << (sc==caracter) << endl;

	Simbolo simboloUnsignedChar=caracter;
	Simbolo simboloChar=sc;
	cout << "Si asigno un char con valor 255 a un simbolo y si asigno " <<
		"un unsigned char también con valor 255 a otro simbolo, " <<
		"entonces los valores de dichos simbolos difieren: " <<
		(simboloChar!=simboloUnsignedChar) << endl;
	cout << "valor de simboloChar: " << simboloChar << endl;
	cout << "valor de simboloUnsignedChar: " << simboloUnsignedChar << endl;
	*/



	return 0;
}
